/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
 */

package com.xinyue.game.gateway.server.websocket;

import com.xinyue.game.gateway.common.GameGatewayMessageResponseHeader;
import com.xinyue.game.message.GameServerMessageModel;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Base64Utils;

/**
 * 游戏网络通信编码Handler，负责处理向网络层发送消息之前，将消息序列化为ByteBuf
 *
 * @author 王广帅
 * @since 2021/5/30 19:12
 */
public class WebSocketEncoderHandler extends ChannelOutboundHandlerAdapter {
    private static Logger logger = LoggerFactory.getLogger(WebSocketEncoderHandler.class);

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        if (msg instanceof GameServerMessageModel) {
            GameServerMessageModel<GameGatewayMessageResponseHeader> messageModel = (GameServerMessageModel<GameGatewayMessageResponseHeader>) msg;
            GameGatewayMessageResponseHeader header = messageModel.getHeader();
            int size = 4 + header.getHeaderSize();
            if (messageModel.getBody() != null) {
                size += messageModel.getBody().readableBytes();
            }
            ByteBuf byteBuf = Unpooled.buffer(size);
            byteBuf.writeInt(size);
            // 写入包头信息
            header.write(byteBuf);
            byte[] bytes = new byte[size];
            if (messageModel.getBody() == null) {
                byteBuf.readBytes(bytes);
            } else {
                ByteBuf newBuf = Unpooled.wrappedBuffer(byteBuf, messageModel.getBody());
                newBuf.readBytes(bytes);
            }
            logger.debug("websocket response -> header: {}, body: {}", messageModel.getHeader(), messageModel.getBodyStr());
            ctx.writeAndFlush(new TextWebSocketFrame(Base64Utils.encodeToString(bytes)), promise);
        } else {
            ctx.writeAndFlush(msg, promise);
        }
    }
}
